# coding=utf8
import numpy as np

import operator


def createDataSet():
    groups = np.array([
        [1.0, 1.1],
        [1.0, 1.0],
        [0, 0],
        [0, 0.1]
    ])
    labels = ['A', 'A', 'B', 'B']

    return groups, labels


def classify0(inX, dataSet, labels, k):
    """
    :param inX: 需要分类的输入向量
    :param dataSet:训练样本集合
    :param labels:标签向量
    :param k:选择的邻居数目
    :return:
    """
    dataSetSize = dataSet.shape[0]
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat ** 2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances ** 0.5
    sortedDistIndicides = distances.argsort()
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicides[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]


import unittest


class TestClassify0(unittest.TestCase):
    def test_1(self):
        groups, labels = createDataSet()
        self.assertEqual(classify0([0, 0], groups, labels, 3), 'B')
        self.assertEqual(classify0([0.1, 0], groups, labels, 3), 'B')
        self.assertEqual(classify0([0.1, 0.1], groups, labels, 3), 'B')
        self.assertEqual(classify0([1.1, 1.1], groups, labels, 3), 'A')


# if __name__ == '__main__':
# unittest.main()


def file2matrix(filename):
    love_dictionary = {'largeDoses': 3, 'smallDoses': 2, 'didntLike': 1}
    arrayOLines = open(filename).readlines()
    returnMat = np.zeros((len(arrayOLines), 3), dtype=float)
    classLabelVector = []
    for index, line in enumerate(arrayOLines):
        listFromLine = line.strip().split('\t')
        returnMat[index, :] = listFromLine[0:3]
        classLabelVector.append(love_dictionary.get(listFromLine[-1], -1))
    return returnMat, classLabelVector


def autoNorm(dataSet):
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    # normDataSet = np.zeros(np.shape(dataSet))
    m = dataSet.shape[0]
    normDataSet = dataSet - np.tile(minVals, (m, 1))
    normDataSet = normDataSet / np.tile(ranges, (m, 1))
    return normDataSet, ranges, minVals


def datingClassTest():
    hoRatio = 0.10
    datingDataMat, datingLabels = file2matrix('datingTestSet.txt')
    normMat, ranges, minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m * hoRatio)
    errorCount = 0
    for i in range(numTestVecs):
        classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
        if classifierResult != datingLabels[i]:
            errorCount += 1
    print 'the total error rate is : %f' % (errorCount / float(numTestVecs))


if __name__ == '__main__':
    pass
    # unittest.main()
    # datingClassTest()

    # dataSet, labelSet = file2matrix('datingTestSet.txt')
    # normMat, ranges, minVals = autoNorm(dataSet)

